package com.it.gmall.realtime.util;

import com.it.gmall.realtime.bean.DauInfo;
import com.it.gmall.realtime.bean.Movie;
import com.it.gmall.realtime.bean.Person;
import io.searchbox.action.Action;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.JestResult;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.core.*;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.MatchQueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author : code1997
 * @date :2021-01-2021/1/26 23:23
 */
public class ESUtil {
    private static JestClientFactory factory = null;

    public static JestClient getJestClient() {
        if (factory == null) {
            build();
        }
        return factory.getObject();
    }

    private static void build() {
        factory = new JestClientFactory();
        factory.setHttpClientConfig(new HttpClientConfig.Builder("http://hadoop02:9200").multiThreaded(true)
                .maxTotalConnection(20)
                .connTimeout(10000)
                .readTimeout(1000).build());

    }

    /**
     * 方式1：写起来不是很方便
     */
    public static void putIndex() {
        //获取客户端
        JestClient jestClient = getJestClient();
        //通过客户端对象操作对象:source的对象是Object，说明什么都是可以的。
        String source = "{\n" +
                "    \"id\":100,\n" +
                "    \"name\":\"operation red sea\",\n" +
                "    \"doubanScore\":8.5,\n" +
                "    \"actorList\":[\n" +
                "      {\"id\":1,\"name\":\"zhang yi\"},\n" +
                "      {\"id\":2,\"name\":\"hai qing\"},\n" +
                "      {\"id\":3,\"name\":\"zhang han yu\"}\n" +
                "    ]\n" +
                "  }";
        Index index = new Index.Builder(source)
                .index("movie_index_5")
                .type("movie")
                .id("1")
                .build();
        //传入的Action是接口类型,不同的操作有不同的实现类。
        try {
            jestClient.execute(index);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                jestClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * 方式2：将样例对象转换为json
     */
    public static void putIndexByJson() {
        //获取客户端
        JestClient jestClient = getJestClient();
        //通过客户端对象操作对象:source的对象是Object，说明什么都是可以的。
        ArrayList<Person> actorList = new ArrayList<>();
        actorList.add(new Person(1L, "赵薇"));
        actorList.add(new Person(2L, "赵四"));
        actorList.add(new Person(3L, "田七"));
        Index index = new Index.Builder(new Movie(1L, "天龙八部", 88.90f, actorList))
                .index("movie_index_5")
                .type("movie")
                .id("2")
                .build();
        //传入的Action是接口类型,不同的操作有不同的实现类。
        try {
            jestClient.execute(index);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                jestClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void queryIndexById() {
        JestClient jestClient = getJestClient();
        //传入的Action是接口类型,不同的操作有不同的实现类。
        Action get = new Get.Builder("movie_index_5", "2").build();
        try {
            JestResult execute = jestClient.execute(get);
            System.out.println(execute.getJsonString());

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                jestClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据条件查询多个文档
     */
    public static void queryByCondition() {
        JestClient jestClient = getJestClient();
        //传入的Action是接口类型,不同的操作有不同的实现类。

        String query =
                "{\n" +
                        "  \"query\":{\n" +
                        "    \"bool\": {\n" +
                        "      \"must\": [\n" +
                        "        {\n" +
                        "          \"match\": {\n" +
                        "            \"name\": \"red\"\n" +
                        "          }\n" +
                        "        }\n" +
                        "      ],\n" +
                        "      \"filter\": [\n" +
                        "        {\n" +
                        "          \"term\":{\"actorList.name.keyword\":\"zhang yi\"}\n" +
                        "        }  \n" +
                        "      ]\n" +
                        "    }\n" +
                        "  },\n" +
                        "  \"from\":0,\n" +
                        "  \"size\": 20,\n" +
                        "  \"sort\": [\n" +
                        "    {\n" +
                        "      \"doubanScore\": {\n" +
                        "        \"order\": \"desc\"\n" +
                        "      }\n" +
                        "    }\n" +
                        "  ],\n" +
                        "  \"highlight\": {\n" +
                        "    \"fields\": {\n" +
                        "      \"name\":{}\n" +
                        "    }\n" +
                        "  }\n" +
                        "}";
        try {
            Search build = new Search.Builder(query).addIndex("movie_index_5").build();
            JestResult execute = jestClient.execute(build);
            execute.getSourceAsStringList().forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                jestClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 根据条件查询多个文档
     */
    public static void queryByCondition2() {
        JestClient jestClient = getJestClient();
        //传入的Action是接口类型,不同的操作有不同的实现类。
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(new MatchQueryBuilder("name", "red"));
        boolQueryBuilder.filter(new TermQueryBuilder("actorList.name.keyword", "zhang yi"));
        sourceBuilder.query(boolQueryBuilder)
                .from(0)
                .size(20)
                .sort("doubanScore", SortOrder.DESC)
                .highlighter(new HighlightBuilder().field("name"));
        System.out.println(sourceBuilder);
        try {
            Search build = new Search.Builder(sourceBuilder.toString()).addIndex("movie_index_5").build();
            JestResult execute = jestClient.execute(build);
            System.out.println("---------------查出的数据---------------");
            execute.getSourceAsStringList().forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭连接
            try {
                jestClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 多条数据插入工作
     */
    public static void bulkInsert(List sourceList, String indexName) throws IOException {
        if (sourceList != null && sourceList.size() > 0) {
            JestClient jestClient = getJestClient();
            Bulk.Builder bulkBuild = new Bulk.Builder();
            for (Object source : sourceList) {
                Index index = new Index.Builder(source)
                        .index(indexName)
                        .type("_doc")
                        .id(((DauInfo) source).getMid())
                        .build();
                bulkBuild.addAction(index);
            }
            Bulk bulk = bulkBuild.build();
            BulkResult bulkResult = jestClient.execute(bulk);
            List<BulkResult.BulkResultItem> items = bulkResult.getItems();
            System.out.println("保存到es中条数为：" + items.size());
            jestClient.close();
        }

    }


    public static void main(String[] args) {
        queryByCondition2();
    }
}
